/*
read in "output_csr_100.txt" for data source
1.use C++ to show the function "matrix_calc_taskA".
and the input parameter is "TaskMatrixInfoA**",which is the same as Guidance.
2.generate random data and bigger matrix.
*/
#include <iostream>
#include <algorithm> //sort()
#include <ctime> //random seed
#include <cstdlib>//rand()
#include <fstream> // ifstream 
using namespace std;

typedef struct {
	int* 			rowArray;
	const int* 		rowOffset;
	int 			rowArraySize;
	const int* 		columnIndice;
	const double* 	S;
	const double*	valueNormalMatrix;
	double* 		Id;
}TaskMatrixInfoA;

void matrix_calc_taskA(TaskMatrixInfoA** listDataList,int N)
{
	for (int it = 0; it < N;++it){
		const int node = (*listDataList)->rowArray[it];
		for (int j = (*listDataList)->rowOffset[node];j < (*listDataList)->rowOffset[node + 1];++j){
			(*listDataList)->Id[node] +=(*listDataList)->valueNormalMatrix[j]* (*listDataList)->S[(*listDataList)->columnIndice[j]];
		}
	}
}

//matrix 1
#define MATRIX_SIZE 940621
#define MATRIX_SHAPE 99340
#define FILE "output_csr_100.txt" 

//matrix 2
//#define MATRIX_SIZE 578890
//#define MATRIX_SHAPE 99190
//#define FILE "output_csr_100s.txt" 

//matrix 3
//#define MATRIX_SIZE 1931828
//#define MATRIX_SHAPE 321821
//#define FILE "output_csr_320.txt" 

//matrix 4
//#define MATRIX_SIZE 1316085
//#define MATRIX_SHAPE 321671
//#define FILE "output_csr_320s.txt" 

//matrix 5
//#define MATRIX_SIZE 2638997
//#define MATRIX_SHAPE 682862
//#define FILE "output_csr_680.txt" 

//matrix 6
//#define MATRIX_SIZE 1693767
//#define MATRIX_SHAPE 682712
//#define FILE "output_csr_680s.txt" 

int columnIndice_[MATRIX_SIZE];
double valueNormalMatrix_[MATRIX_SIZE];

int main()
{
	TaskMatrixInfoA** listData;
	TaskMatrixInfoA* listData_temp=new TaskMatrixInfoA;
	listData = &listData_temp;

	int matrix_shape = MATRIX_SHAPE;
	int matrix_size = MATRIX_SIZE;
	int change_rowsize = MATRIX_SHAPE;
	
//	ifstream in("output_csr_100.txt");
	ifstream in(FILE);
		
	int rowOffset_[matrix_shape+1];
	for(int i= 0 ;i< matrix_shape+1;++i){
		in >> rowOffset_[i];
//		if(i<6 or i>matrix_shape-6){
//			cout<< rowOffset_[i]<<" ";	
//		} 
	}	
//	cout<< endl;

	for(int i =0;i<matrix_size;++i){
		in >> columnIndice_[i];
//		if(i<6 or i> matrix_size-6){
//			cout<< columnIndice_[i]<<" ";
//		} 	
	}
//	cout<<endl;

	for(int i=0;i<matrix_size;++i){
		in >> valueNormalMatrix_[i];
//		if (i<6 or i>matrix_size-6){
//			cout<< valueNormalMatrix_[i]<<" ";
//		}
	}
//	cout<<endl;

	(*listData)->rowArraySize = change_rowsize;
// 1.rowArray	
	int rowArray_[change_rowsize];	
	for(int i=0;i<change_rowsize;i++){
		rowArray_[i]=i;
	} 
	(*listData)->rowArray=rowArray_;
// 2.rowOffset	
	(*listData)->rowOffset=rowOffset_;
// 3.columnIndice	
//	int columnIndice_[9] = {0,1,1,2,0,2,3,0,3};
	(*listData)->columnIndice=columnIndice_;
// 4.S	
	double S_[matrix_shape];
//	double S_[matrix_shape];
	for(int i=0;i<matrix_shape;++i){
		S_[i]=i+1;
	}
	(*listData)->S=S_;
// 5.valueNormalMatrix	
//	double valueNormalMatrix_[9]={1,5,8,3,5,2,4,9,1};
	(*listData)->valueNormalMatrix=valueNormalMatrix_;
// 6.Id
	double Id_[matrix_shape]={0};
	(*listData)->Id=Id_;
	
// show result	
/*	
	cout <<"\n";
	for(int i=0;i<10;++i){
		cout << (*listData)->rowArray[i] <<" ";
	}
	cout<<"\n";

	for(int i=0;i<10;++i){
		cout << (*listData)->rowOffset[i] <<" ";
	}
	cout<<"\n";

	for(int i=0;i<10;++i){
		cout << (*listData)->columnIndice[i] <<" ";
	}
	cout<<"\n";

	for(int i=0;i<10;++i){
		cout << (*listData)->S[i] <<" ";
	}
	cout<<"\n";

	for(int i=0;i<10;++i){
		cout << (*listData)->valueNormalMatrix[i] <<" ";
	}
	cout<<"\n";
*/
	clock_t start,end;
	start = clock();
	matrix_calc_taskA(listData , change_rowsize);
	end = clock();
	cout<<"total time: "<<end-start<<endl;
	
//	for(int i=0;i<6;++i){
//		cout << (*listData)->Id[i] <<" ";
//	}
//	cout<<endl;

	delete(listData_temp);
	return 0;
}

